#include <string>
#include <unistd.h>
#include <sys/socket.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include "Event.h"

namespace Marco
{
   namespace BlueTooth
   {
      class Service
      {
         public:
            Service(){}
            Service(const std::string &serviceUUID,
                    const std::string &serviceName,
                    const std::string &serviceProvider,
                    const std::string &serviceDescription,
                    uint8_t rfcommChannel = 0);
            ~Service();

            sdp_session_t *GetSDPSession(){ return(mSDPSession); }

         private:
            sdp_list_t         *mL2CapList;
            sdp_list_t         *mRFCommList;
            sdp_list_t         *mRootList;
            sdp_list_t         *mProtoList;
            sdp_list_t         *mAccessProtoList;
            sdp_list_t         *mClassIDList;
            sdp_data_t         *mChannel;
            sdp_data_t         *mPSM;
            sdp_record_t       *mSDPRecord;
            sdp_session_t      *mSDPSession;
            bdaddr_t            mBDADDR_ANY;
            std::string         mUUID;
            uint8_t             mRFChannel;
            uuid_t              mRootUUID;
            uuid_t              mL2CapUUID;
            uuid_t              mRFCommUUID;
            uuid_t              mServiceUUID;
      };

      class ClientSocket
      {
         public:
            ClientSocket(int socket);
            ~ClientSocket();

            Event Read();

         private:
            int mSocket;
            char mBuff[1];

            float ntohf( const float inFloat );
      };

      class Server
      {
         public:
            Server(){}
            Server(const std::string &serviceUUID,
                   const std::string &serviceName,
                   const std::string &serviceProvider,
                   const std::string &serviceDescription,
                   uint8_t rfCommChannel = 0);
            ~Server();

            int GetClient(){ return(mClient); }

         private:
            Service  *mSDPService;
            struct sockaddr_rc mLocalAddress;
            struct sockaddr_rc mRemoteAddress;
            socklen_t mOptions;
            int         mSocket;
            int         mClient;
            char        mBuff[1];
      };
   }
}
